﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Pavilion;

namespace Pavilion.Control
{
    public class ColorGrid : Control
    {
        private int gridLength;
        private float hue, increment;
        private CTexture2D gridTexture, cursorTexture;
        private Vector2 cursorPosition;

        public event Action<Color> ColorChanged;

        public ColorGrid(int gridLength) : base()
        {
            this.gridLength = gridLength;
            AreaBounds = new Rectangle(0, 0, gridLength, gridLength - 1);
            CursorPosition = new Vector2(gridLength / 2, gridLength / 2);
            increment = 1f / gridLength;

            RenderColorGrid(0f);
            RenderCursor();

            this.Input.MousePress += new MouseObjectHandler(ColorGrid_MousePress);
            this.Input.MouseMoved += new MouseObjectHandler(ColorGrid_MouseMoved);
        } 

        public override void Draw()
        {
            gridTexture.Draw(new Vector2(ScreenBounds.X, ScreenBounds.Y), Color.White);

            Rectangle bounds = new Rectangle(0, 0, cursorTexture.Width, cursorTexture.Height);
            Vector2 position = new Vector2(ScreenBounds.X + CursorPosition.X, ScreenBounds.Y + CursorPosition.Y);

            if (CursorPosition.X < gridLength / 1.7f)
                cursorTexture.Draw(position, bounds, Color.White, 0f, new Vector2(bounds.Width / 2, bounds.Height / 2), 1f, SpriteEffects.None, 1f);
            else
                cursorTexture.Draw(position, bounds, Color.Black, 0f, new Vector2(bounds.Width / 2, bounds.Height / 2), 1f, SpriteEffects.None, 1f);

            base.Draw();
            DrawManager.Instance.DrawRectangleOnScreen(ScreenBounds, OutlineColor);
        }

        public void RenderColorGrid(float hue)
        {
            Vector2 position = new Vector2(0, 0);
            Render render = new Render();
            float total = 1f;

            this.hue = hue;

            render.Begin(AreaBounds.Width, AreaBounds.Height);

            for (float s = increment; s <= total; s += increment)
            {
                for (float b = 0f; b <= total; b += increment)
                {
                    CColor color = new CColor();
                    DrawManager.Instance.DrawPointOnScreen(position, color.ConvertHsbToRgb(hue, s, b, 255));
                    position.X++;
                }
                position.Y++;
                position.X = 0f;
            }

            render.End();

            gridTexture = new CTexture2D(render.Texture);
        }

        private void RenderCursor()
        {
            Render render = new Render();
            render.Begin(9, 9);

            //Vertical lines
            DrawManager.Instance.DrawLineOnScreen(new Vector2(5, 0), new Vector2(5, 3), Color.White);
            DrawManager.Instance.DrawLineOnScreen(new Vector2(5, 6), new Vector2(5, 9), Color.White);

            //Horizonal lines
            DrawManager.Instance.DrawLineOnScreen(new Vector2(0, 4), new Vector2(3, 4), Color.White);
            DrawManager.Instance.DrawLineOnScreen(new Vector2(6, 4), new Vector2(9, 4), Color.White);

            render.End();

            cursorTexture = new CTexture2D(render.Texture);
        }

        private Color CreateColorByPosition(Vector2 position)
        {
            CColor color = new CColor();

            return color.ConvertHsbToRgb(hue, (position.Y + 1) * increment, position.X * increment, 255);
        }

        /// <summary>
        /// Gets the current color from this color grid.
        /// </summary>
        public Color Color
        {
            get { return CreateColorByPosition(CursorPosition); }
        }

        /// <summary>
        /// Gets or sets the current cursor position.
        /// </summary>
        private Vector2 CursorPosition
        {
            get { return cursorPosition; }
            set
            {
                if (value.X > this.AreaBounds.Width)
                    value.X = AreaBounds.Width;
                else if (value.X < 0)
                    value.X = 0;

                if (value.Y > this.AreaBounds.Height)
                    value.Y = AreaBounds.Height;
                else if (value.Y < 0)
                    value.Y = 0;

                if (cursorPosition.X == value.X && cursorPosition.Y == value.Y)
                    return;

                cursorPosition = value;
                OnColorChanged();
            }
        }

        private void OnColorChanged()
        {
            if (ColorChanged != null)
                ColorChanged(this.Color);
        }

        private void ColorGrid_MousePress(object sender, MouseCursor mouseCursor)
        {
            CursorPosition = new Vector2(mouseCursor.Position.X - ScreenBounds.X, mouseCursor.Position.Y - ScreenBounds.Y);
        }

        private void ColorGrid_MouseMoved(object sender, MouseCursor mouseCursor)
        {
            if (Mouse.GetState().LeftButton == ButtonState.Released && Mouse.GetState().RightButton == ButtonState.Released)
                return;

            CursorPosition = new Vector2(mouseCursor.Position.X - ScreenBounds.X, mouseCursor.Position.Y - ScreenBounds.Y);
        }
    }
}
